<script setup lang="ts">
import type { FormConfigModel, FormConfigElement } from '../shared'
import { VueDraggable } from 'vue-draggable-plus'
import { NForm, NScrollbar, type FormInst } from 'naive-ui'
import { ref } from 'vue'

import DynamicFormItem from '../components/DynamicFormItem.vue'
import DynamicFormItemSubset from '../components/DynamicFormItemSubset.vue'
import FormPreviewItemTitle from '../components/FormPreviewItemTitle.vue'
import DynamicFormItemHandles from '../components/DynamicFormItemHandles.vue'

defineProps<{ value: FormConfigModel[] }>()
defineEmits<{
  (event: 'setting:group', value: FormConfigModel): void
  (event: 'setting:item', value: FormConfigElement): void

  (event: 'delete:group', parent: FormConfigModel[], index: number): void
  (event: 'delete:item', parent: FormConfigElement[], index: number): void
}>()

const formData = ref({} as Record<string, any>)
const formInst = ref<FormInst | null>(null)

const handleAddSubItem = (k: string) => {
  const subItems = formData.value[k] || []
  subItems.push({})
  formData.value[k] = subItems
}
const handleDeleteSubItem = (k: string, i: number) => {
  const subItems = formData.value[k]
  if (subItems) {
    subItems.splice(i, 1)
    formData.value[k] = subItems
  }
}

document.addEventListener('form-preview:submit', (e) => {
  formInst.value?.validate((err) => {
    console.log(e.type, formData.value)
    if (err) return
  })
})
</script>

<template>
  <div class="form-preview">
    <NScrollbar style="max-height: 100%">
      <NForm
        ref="formInst"
        :model="formData"
        label-placement="left"
        require-mark-placement="left"
      >
        <div
          v-for="(e, i) in value"
          :key="i"
          class="form-preview__block"
        >
          <DynamicFormItemHandles
            @setting="$emit('setting:group', e)"
            @delete="$emit('delete:group', value, i)"
          >
            <template #prefix>
              <FormPreviewItemTitle
                v-if="e.title"
                :title="e.title"
              />
            </template>
          </DynamicFormItemHandles>

          <template v-if="e.subset">
            <DynamicFormItemSubset
              :subset="e.subset"
              :data="formData"
              @add:subItem="handleAddSubItem"
              @delete:subItem="handleDeleteSubItem"
            >
              <template #default="{ key, value }">
                <VueDraggable
                  v-model:model-value="e.subset[key]"
                  :group="key"
                  :animation="150"
                  class="form-preview__draggable"
                >
                  <DynamicFormItemHandles
                    v-for="(c, ci) in value"
                    :key="ci"
                    @setting="$emit('setting:item', c)"
                    @delete="$emit('delete:item', e.elements, ci)"
                  >
                    <template #prefix>
                      <DynamicFormItem
                        :config="c"
                        style="flex: 1"
                        flex="1"
                        :vars="{ formData }"
                      />
                    </template>
                  </DynamicFormItemHandles>
                </VueDraggable>
              </template>
              <template #subItems="{ elements }">
                <div class="form-preview__draggable">
                  <DynamicFormItem
                    v-for="(c, ci) in elements"
                    :key="ci"
                    :config="c"
                    flex="1"
                    style="flex: 1"
                    :vars="{ formData }"
                  />
                </div>
              </template>
            </DynamicFormItemSubset>
          </template>

          <VueDraggable
            v-model:model-value="e.elements"
            group="elements"
            :animation="150"
            class="form-preview__draggable"
          >
            <DynamicFormItemHandles
              v-for="(c, ci) in e.elements"
              :key="ci"
              @setting="$emit('setting:item', c)"
              @delete="$emit('delete:item', e.elements, ci)"
            >
              <template #prefix>
                <DynamicFormItem
                  :config="c"
                  style="flex: 1"
                  flex="1"
                  :vars="{ formData }"
                />
              </template>
            </DynamicFormItemHandles>
          </VueDraggable>
        </div>
      </NForm>
    </NScrollbar>
  </div>
</template>

<style scoped>
.form-preview {
  padding: 10px;
}

.form-preview__draggable {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0 20px;
  min-height: 50px;
  padding: 10px 15px;
  list-style: none;
  margin-bottom: 5px;
  background-color: var(--group-bg-color);
}

.form-preview__block {
  margin-bottom: 20px;
}

.form-preview__block:last-child {
  margin-bottom: 0;
}
</style>
